/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sourcery;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.event.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.Timer;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import sourceryobjects.sRelationType;
import sourceryobjects.SceneGraph;
import sourceryobjects.sNode;
import sourceryobjects.sRelation;

/**
 *
 * @author claire
 */
public class MainPanel extends JPanel implements ActionListener {

    private final static BasicStroke stroke = new BasicStroke(3.0f);
    private final static boolean AUTOLOAD = true;
    private final static int DEFAULTWIDTH = 20;
    private SceneGraph scene;

    public SceneGraph getScene() {
        return scene;
    }
    private MouseHandler mouser;
    private KeyboardHandler keyber;
    private boolean connecting;
    private sRelation activeConnection;
    private static sRelationType connectionMode;

    public static sRelationType getConnectionMode() {
        return connectionMode;
    }

    public MainPanel() {
        super();
        mouser = new MouseHandler();
        keyber = new KeyboardHandler(this);
        this.addKeyListener(keyber);
        this.addMouseListener(mouser);
        this.addMouseMotionListener(mouser);
        this.setFocusable(true);

        if (AUTOLOAD) {
            load();
        }
        if(scene == null)
        {
            scene = new SceneGraph();
            connectionMode = new sRelationType(1.0, 0.0, GraphicsContext.LineStyles.NONE);
            connectionMode.setName("Mouse");
            scene.addRelationType(connectionMode);
            connectionMode = new sRelationType(1.0, 100.0, GraphicsContext.LineStyles.GREEN);
            connectionMode.setName("Green");
            scene.addRelationType(connectionMode);
            mouser.attachToScene(scene);
            connectionMode = scene.getRelationType(1);
        }
        
        new Timer(3, this).start();
    }

    public void addNode(sNode newdraw) {
        scene.add(newdraw);
    }

    public void newNodeAtMouse() {
        scene.add(new sNode(mouser.getX(), mouser.getY()));
    }

    public void newNodeAt(double x, double y) {
        scene.add(new sNode(mouser.getX(), mouser.getY()));
    }

    public void doConnector() {
        sNode p = mouser.findNode();
        if (p != null && activeConnection == null) {
            activeConnection = new sRelation(p, mouser.getPoint(), connectionMode);
            scene.addRelation(activeConnection);

        } else if (p != null && activeConnection != null && p != activeConnection.getA()) {
            activeConnection.connectTo(p);
            activeConnection = null;
        } else {
            scene.removeRelation(activeConnection);
            activeConnection = null;
        }
    }

    /**
     * Called every time the surface needs to be repainted.
     *
     * @param g
     *            the surface to be painted
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        GraphicsContext gc = new GraphicsContext(g);
        scene.draw(gc);
    }

    public void actionPerformed(ActionEvent e) {
        scene.update();
        repaint();
    }

    public void save() {
        save("data.dat");
    }

    public void save(String filename) {
        System.out.println("Saving to " + filename + "...");
        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(filename);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(scene);
            oos.close();
            fos.close();
            System.out.println("Saving to " + filename + " complete!");
        } catch (IOException ex) {
            System.out.println("Saving to " + filename + " failed!");
            ex.printStackTrace();
        }
    }

    public void load() {
        load("data.dat");
    }

    public void load(String filename) {
        System.out.println("Loading from " + filename + "...");
        FileInputStream fis = null;
        ObjectInputStream ois = null;
        try {
            fis = new FileInputStream(filename);
            ois = new ObjectInputStream(fis);
            scene = (SceneGraph) ois.readObject();
            ois.close();
            fis.close();
            mouser.attachToScene(scene);
            connectionMode = scene.getRelationType(1);

            System.out.println("Loading from " + filename + " complete!");
        } catch (IOException ex) {
            System.out.println("Loading from " + filename + " failed due to IO!");
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            System.out.println("Loading from " + filename + " failed due to class!");
            ex.printStackTrace();
        }
    }

    void editRelations() {
        final JFrame frame = (JFrame) this.getTopLevelAncestor();
        final JDialog dialog = new JDialog(frame, "Editing Relation Types");

        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new BorderLayout());
            JPanel listPanel = new JPanel();
                DefaultListModel listModel = new DefaultListModel();
                for(int i=0;i<scene.countRelationTypes();i++){
                    listModel.addElement(scene.getRelationType(i).getName());
                }

                JList listBox = new JList(listModel);
                    listBox.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                    listBox.setSelectedIndex(0);
                    listBox.setVisibleRowCount(10);
                JScrollPane listScrollPane = new JScrollPane(listBox);
                listPanel.add(listScrollPane);
            contentPanel.add(listPanel, BorderLayout.CENTER);

            JPanel buttonPanel = new JPanel();
                final JButton editButton = new JButton("Edit");
                final MainPanel panelizer = this;
                editButton.addActionListener(new ActionListener() {
                   public void actionPerformed(ActionEvent e) {
                       RelationTypeEditor p = new RelationTypeEditor(panelizer,
                           scene.getRelationType(Integer.parseInt(e.getActionCommand()))
                       );
                       p.edit();
                       dialog.setVisible(false);
                       dialog.dispose();
                   }
                });
                listBox.addListSelectionListener(new ListSelectionListener() {
                   public void valueChanged(ListSelectionEvent e) {
                       JList source = (JList) e.getSource();
                       editButton.setActionCommand(source.getSelectedIndex() + "");
                   }
                });
                editButton.setActionCommand("0");
                buttonPanel.add(editButton);

                JButton closeButton = new JButton("Close");
                closeButton.addActionListener(new ActionListener() {
                   public void actionPerformed(ActionEvent e) {
                       dialog.setVisible(false);
                       dialog.dispose();
                   }
                });
                buttonPanel.add(closeButton);
            contentPanel.add(buttonPanel, BorderLayout.SOUTH);
        dialog.setContentPane(contentPanel);

        dialog.setSize(new Dimension(300, 300));
        dialog.setVisible(true);
    }



    void editNodes() {
    }
}
